package com.zhonghui.modlules.auth.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eshop.apiCode.EshopException;
import com.zhonghui.common.bean.LocalUser;
import com.zhonghui.common.enums.SmsTypeEnum;
import com.zhonghui.common.eshopConstant.ShopConstants;
import com.zhonghui.common.eshopDomain.ShopUser;
import com.zhonghui.common.eshopEnum.ShopCommonEnum;
import com.zhonghui.common.eshopUtil.ApiResult;
import com.zhonghui.common.eshopUtil.RedisUtils;
import com.zhonghui.common.util.JwtToken;
import com.zhonghui.common.util.SmsUtils;
import com.zhonghui.modlules.auth.param.HLoginParam;
import com.zhonghui.modlules.auth.param.RegParam;
import com.zhonghui.modlules.auth.param.VerityParam;
import com.zhonghui.modlules.auth.services.AuthService;
import com.zhonghui.modlules.user.eshopService.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
@Api(value = "认证模块",tags = "认证模块")
public class AuthController {

    private final UserService userService;
    private final RedisUtils redisUtils;
    private final AuthService authService;


    @Value("${single.login}")
    public Boolean singleLogin;

    @ApiOperation(value = "H5登录授权",notes = "H5登录授权")
    @PostMapping("/login")
    public ApiResult<Map<String,Object>> login(@Validated HLoginParam loginParam){
        ShopUser shopUser = userService.getOne(Wrappers.<ShopUser>lambdaQuery()
                .eq(ShopUser::getUsername, loginParam.getUsername())
                .eq(ShopUser::getPassword, SecureUtil.md5(loginParam.getPassword())));
        if (shopUser == null){
            throw new EshopException("用户名或者密码错误");
        }

        String token = JwtToken.makeToken(shopUser.getUid(), shopUser.getUsername());
        String expireTime = JwtToken.getExpireTime(token);

        Map<String, Object> map = new HashMap<String, Object>(2) {{
            put("token", token);
            put("expire_time", expireTime);
        }};

        userService.setSpread(loginParam.getSpread(),shopUser.getUid());

        return ApiResult.ok(map).setMsg("登录成功");
    }


    @ApiOperation(value = "H5/APP注册新用户",notes = "H5/APP注册新用户")
    @PostMapping("/register")
    public ApiResult<String> register(@Validated @RequestBody RegParam regParam){
        Object codeObje = redisUtils.get("code_" + regParam.getAccount());
        if (codeObje == null){
            return ApiResult.fail("请先获取验证码");
        }

        String code = codeObje.toString();
        if (!StrUtil.equals(code,regParam.getAccount())){
            return ApiResult.fail("验证码错误");
        }

        ShopUser shopUser = userService.getOne(Wrappers.<ShopUser>lambdaQuery()
                .eq(ShopUser::getPhone, regParam.getAccount()), false);

        if (ObjectUtil.isNotNull(shopUser)){
            return ApiResult.fail("手机号存在");
        }

        authService.register(regParam);
        return ApiResult.ok("","注册成功");
    }

    @ApiOperation(value = "短信发送验证码",notes = "短信发送验证码")
    @PostMapping("/register/verify")
    public ApiResult<String> verify(@Validated @RequestBody VerityParam param){
        ShopUser shopUser = userService.getOne(Wrappers.<ShopUser>lambdaQuery()
                .eq(ShopUser::getPhone, param.getPhone()), false);
        if (SmsTypeEnum.REGISTER.getValue().equals(param.getType()) || ObjectUtil.isNotNull(shopUser)){
            return ApiResult.fail("手机号已注册");
        }
        if (SmsTypeEnum.LOGIN.getValue().equals(param.getType()) || ObjectUtil.isNull(shopUser)){
            return ApiResult.fail("账号不存在");
        }

        String codeKey = "code_"+param.getPhone();
        if (ObjectUtil.isNotNull(redisUtils.get(codeKey))){
            return ApiResult.fail("10分钟内有效"+redisUtils.get(codeKey).toString());
        }
        String code = RandomUtil.randomNumbers(ShopConstants.YSHOP_SMS_SIZE);
        redisUtils.set(codeKey,code,ShopConstants.YSHOP_ORDER_CACHE_TIME);

        String enable = redisUtils.getY("enable");
        if (ShopCommonEnum.ENABLE_2.getValue().toString().equals(enable)){
            return ApiResult.ok(code);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code",code);

        try {
            //toJSONString <--> 将java对象序列化为JSON字符串 fastjson提供了一个最简单的入口
            SmsUtils.sendSms(param.getPhone(),jsonObject.toJSONString());
        } catch (ClientException e) {
            redisUtils.del(codeKey);
            e.printStackTrace();
            return ApiResult.ok("发送失败"+e.getErrMsg());
        }
        return ApiResult.ok("发送成功，请注意查收");
    }

    @ApiOperation(value = "退出登录",notes = "退出登录")
    @PostMapping("/logout")
    public ApiResult<String> logout(HttpServletRequest request){
        String bearerToken = request.getHeader("Authorization");
        String[] tokens = bearerToken.split(" ");
        String token = tokens[1];
        authService.logout(LocalUser.getUser().getUsername(),token);
        return ApiResult.ok("推出成功");
    }

}
